


#ifndef SHAPEBUILDER_H
#define SHAPEBUILDER_H

#include "Triangle.h"
#include "MatrixBuilder.h"


template<unsigned int TriangleCount>
struct Shape
{
	enum { Size = TriangleCount };

	Shape& transform(const Matrix3D& coordinate)
	{
		for(unsigned int i=0;i<Size;++i)
		{
			triangle_list[i].transform(coordinate);
		}
		return *this;
	}

	template<unsigned int NewCount>
	void set(const Shape<NewCount>& shape,unsigned int index)
	{
		for(unsigned int i=index;i< min(Size,NewCount+index);++i)
		{
			triangle_list[i] = shape.triangle_list[i - index];
		}
	}
	
	Triangle triangle_list[Size];

};

struct Quadrilateral : public Shape<2>
{
	Quadrilateral(){}
	Quadrilateral(const Point3D& pt1,const Point3D& pt2,const Point3D& pt3,const Point3D& pt4,COLORREF color = RGB(255,255,255))
	{
		triangle_list[0] = Triangle(pt1,pt2,pt3,color);
		triangle_list[1] = Triangle(pt1,pt3,pt4,color);
	}
	Quadrilateral(const UVPoint3D& pt1,const UVPoint3D& pt2,const UVPoint3D& pt3,const UVPoint3D& pt4,TexturePtr texture)
	{
		triangle_list[0] = Triangle(pt1,pt2,pt3,texture);
		triangle_list[1] = Triangle(pt1,pt3,pt4,texture);
	}
};

struct Qube : public Shape<Quadrilateral::Size*6>
{
	Qube(){}
	Qube(const Point3D& center,Float3D length,COLORREF color1=RGB(255,0,0),COLORREF color2=RGB(0,255,0),COLORREF color3=RGB(0,0,255) )
	{

		set(	Quadrilateral(
					build_point_3D(-length,-length,-length),
					build_point_3D(-length,length,-length),
					build_point_3D(length,length,-length),
					build_point_3D(length,-length,-length),color1	).transform( move_XYZ(center(0,0),center(1,0),center(2,0) ) * rotate_X(90.0f/180*PI)  ), 0);

		set(	Quadrilateral(
					build_point_3D(-length,-length,-length),
					build_point_3D(-length,length,-length),
					build_point_3D(length,length,-length),
					build_point_3D(length,-length,-length),color1	).transform( move_XYZ(center(0,0),center(1,0),center(2,0) )*rotate_X(-90.0f/180*PI)  ), 2);

		set(	Quadrilateral(
					build_point_3D(-length,-length,-length),
					build_point_3D(-length,length,-length),
					build_point_3D(length,length,-length),
					build_point_3D(length,-length,-length),color2	).transform( move_XYZ(center(0,0),center(1,0),center(2,0) )*rotate_Y(90.0f/180*PI)  ), 4);

		set(	Quadrilateral(
					build_point_3D(-length,-length,-length),
					build_point_3D(-length,length,-length),
					build_point_3D(length,length,-length),
					build_point_3D(length,-length,-length),color2	).transform( move_XYZ(center(0,0),center(1,0),center(2,0) )*rotate_Y(-90.0f/180*PI)  ), 6);

		set(	Quadrilateral(
					build_point_3D(-length,-length,-length),
					build_point_3D(-length,length,-length),
					build_point_3D(length,length,-length),
					build_point_3D(length,-length,-length),color3	).transform( move_XYZ(center(0,0),center(1,0),center(2,0) ) ), 8) ;

		set(	Quadrilateral(
					build_point_3D(-length,-length,-length),
					build_point_3D(-length,length,-length),
					build_point_3D(length,length,-length),
					build_point_3D(length,-length,-length),color3	).transform( move_XYZ(center(0,0),center(1,0),center(2,0) )*rotate_X(180.0f/180*PI)  ), 10);

	}

	Qube(const UVPoint3D& center,Float3D length,Float3D ufinal,Float3D vfinal,TexturePtr texture )
	{
		Quadrilateral square(
					build_uv_point(-length,-length,-length,center(3,0),vfinal),
					build_uv_point(-length,length,-length,center(3,0),center(4,0)),
					build_uv_point(length,length,-length,ufinal,center(4,0)),
					build_uv_point(length,-length,-length,ufinal,vfinal),
					texture );

		set( Quadrilateral(square).transform( move_XYZ(center(0,0),center(1,0),center(2,0) ) * rotate_X(90.0f/180*PI)  ), 0);
		set( Quadrilateral(square).transform( move_XYZ(center(0,0),center(1,0),center(2,0) )*rotate_X(-90.0f/180*PI)  ), 2);
		set( Quadrilateral(square).transform( move_XYZ(center(0,0),center(1,0),center(2,0) )*rotate_Y(90.0f/180*PI)  ), 4);
		set( Quadrilateral(square).transform( move_XYZ(center(0,0),center(1,0),center(2,0) )*rotate_Y(-90.0f/180*PI)  ), 6);
		set( Quadrilateral(square).transform( move_XYZ(center(0,0),center(1,0),center(2,0) ) ), 8) ;
		set( Quadrilateral(square).transform( move_XYZ(center(0,0),center(1,0),center(2,0) )*rotate_X(180.0f/180*PI)  ), 10);
	}
};













#endif